//http://blogrium.com/2006/01/28/joshua/
//Thanks to Jeff Lindsay

Console = Class.create();
Object.extend(Console.prototype, {
	initialize: function(element) {
		this.container = $(element);
		
		this.cmdHistory = [];
		this.cmdHistoryIndex = -1;
		this.cmdBuffer = '';
		this.doubleTab = false;
		this.clearSignal = false;
		
		this.stdin = document.createElement('input');
		this.stdin.type = 'text';
		this.stdin.style.height = 1;
		this.stdin.style.width = 1;
		Event.observe(this.stdin, "keyup", this.onKey.bindAsEventListener(this));
		
		this.stdout = document.createElement('div');
		this.stdout.className = 'stdout';
		Event.observe(this.stdout, "click", this.focus.bindAsEventListener(this));
		
		this.tabCatcher = document.createElement('input');
		this.tabCatcher.type = 'text';
		this.tabCatcher.style.height = 1;
		this.tabCatcher.style.width = 1;
		Event.observe(this.tabCatcher, "focus", this.focus.bindAsEventListener(this));
		
		this.container.appendChild(this.stdout);
		this.container.appendChild(this.stdin);
		this.container.appendChild(this.tabCatcher);
		
		//this.puts("IronPython 1.0.60816 on .NET 2.0.50727.42");
		//this.puts(navigator.appName + " [" + navigator.appCodeName + "] " + navigator.appVersion + " on " + navigator.platform);
		//this.puts("");
		this.prompt();
	}, 
	
	focus: function()
	{
		this.stdin.focus();
	},
	
	prompt: function(buffer) {
		if (!buffer) buffer = '';
		this.stdinEcho = document.createElement('div');
		this.stdinEcho.className = 'stdin';
		this.stdinEcho.innerHTML = '>>> ' + buffer;
		//this.stdinEcho.innerHTML = buffer;
		this.stdout.appendChild(this.stdinEcho);
		this.cmdBuffer = buffer;
		//this.stdin.focus();  //TODO: need a way to set focus or do I?
		this.stdout.scrollTop = this.stdout.scrollHeight;
	},
	
	puts: function(text)
	{
		//this.stdout.innerHTML = this.stdout.innerHTML + text.escapeHTML() + '<br />';
		this.stdout.innerHTML = this.stdout.innerHTML + text.escapeHTML();	
	},
	
	onKey: function(event)
	{
		if (event.keyCode == Event.KEY_TAB) {
			var pos = 0;
			if (-1 == (pos = this.cmdBuffer.lastIndexOf('.'))) {
				var context = window;
				var contextString = '';
				var partial = this.cmdBuffer;
			} else {
				var contextString = this.cmdBuffer.substr(0, pos);
				var context = eval(contextString);
				contextString = contextString + '.';
				var partial = this.cmdBuffer.substr(pos+1);
			}
			var results = [];
			for (var symbol in context) {
				results.push(symbol);
			}
			results = results.grep(new RegExp('^'+partial));
			if (results.length == 1) {
				this.cmdBuffer = contextString + results[0];
			} else if (results.length > 1 && this.doubleTab) {
				this.puts(results.join(' '));
				this.doubleTab = false;
				this.prompt(this.cmdBuffer);
			} else {
				this.doubleTab = true;
			}
		} else if (event.keyCode == Event.KEY_BACKSPACE) {
			this.cmdBuffer = this.cmdBuffer.substr(0, this.cmdBuffer.length - 1);
		} else if (event.keyCode == Event.KEY_RETURN) {
			//MNB if (this.cmdBuffer != '') {
				try {
				//here is our point to pass to server
				
				this.puts(TestCall(this.cmdBuffer));
				//this.puts('=> ' + eval(this.cmdBuffer));  //orginal call
				} catch (e) {
					this.puts(e.message);
				}
			//MNB}
			if (this.clearSignal) {
				this.clearSignal = false;
				this.stdout.innerHTML = '';
			}
			this.cmdHistoryIndex = -1;
			this.cmdHistory.unshift(this.cmdBuffer);
			this.prompt();
		} else if (event.keyCode == Event.KEY_UP) {
			this.cmdHistoryIndex++;
			if (this.cmdHistoryIndex == this.cmdHistory.length) this.cmdHistoryIndex = 0;
			this.cmdBuffer = this.cmdHistory[this.cmdHistoryIndex];
		} else if (event.keyCode == Event.KEY_DOWN) {
			this.cmdHistoryIndex--;
			if (this.cmdHistoryIndex < 0) {
				this.cmdHistoryIndex = -1;
				this.cmdBuffer = '';
			} else {
				this.cmdBuffer = this.cmdHistory[this.cmdHistoryIndex];
			}
		}
		this.cmdBuffer = this.cmdBuffer + this.stdin.value;
		this.stdinEcho.innerHTML = '>>> ' + this.cmdBuffer;
		//this.stdinEcho.innerHTML = this.cmdBuffer;
		this.stdin.value = '';
	}
});